package com.deep.deepenterpise.common.util;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * @author xyz
 * @version 1.0
 * @title DrAESUtil
 * @description
 * @create 2024/4/24 10:24
 */
@Slf4j
public class DrAESUtil {
    private static Cipher cipher;

    private static Cipher ecbCipher;

    private DrAESUtil() {
    }

    static {
        try {
            cipher = Cipher.getInstance(DrEncryptionConstants.DEFAULT_AES);
            ecbCipher = Cipher.getInstance(DrEncryptionConstants.ECB_AES);
        } catch (Exception e) {
            log.info("[AES加密初始化失败]-------" + DrCommonUtil.drGetStackTraceInfo(e));
        }
    }


    public static String encrypt(String plainText, String key, String iv) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(key), DrEncryptionConstants.ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decryptBase64(String encryptedText, String key, String iv) throws Exception {
        return decrypt(encryptedText, Base64.getDecoder().decode(key), iv);
    }

    public static String decryptNoBase64(String encryptedText, String key, String iv) throws Exception {
        return decrypt(encryptedText, key.getBytes(), iv);
    }

    private static String decrypt(String encryptedText, byte[] keys, String iv) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(keys, DrEncryptionConstants.ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }

    public static String encrypt(String plainText, String key) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(key), DrEncryptionConstants.ALGORITHM);
        ecbCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] encryptedBytes = ecbCipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);

    }

    public static String decrypt(String encryptedText, String key) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(key), DrEncryptionConstants.ALGORITHM);
        ecbCipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
        byte[] decryptedBytes = ecbCipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }
}

class DrEncryptionConstants {
    private DrEncryptionConstants() {
    }

    public static final String ALGORITHM = "AES";
    private static final String MODE = "CBC";

    private static final String MODE_ECB = "ECB";
    private static final String PADDING = "PKCS5Padding";
    public static final String DEFAULT_AES = ALGORITHM + "/" + MODE + "/" + PADDING;
    public static final String ECB_AES = ALGORITHM + "/" + MODE_ECB + "/" + PADDING;

}
